#!/usr/bin/env python3
"""
开源安全创意工坊 - Flask 后端主应用
作者：Inscode AI
功能：为网络空间安全专业新生提供开源创意项目协作平台
"""

from flask import Flask, render_template, request, jsonify, redirect, url_for, send_file
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, date
import json
import os
import qrcode
from io import BytesIO
import markdown
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
import random

app = Flask(__name__)
app.config['SECRET_KEY'] = 'opensource-security-creative-workshop-2024'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///creative_workshop.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# 数据库模型
class Project(db.Model):
    """项目模型"""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=False)
    github_url = db.Column(db.String(200))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    team_members = db.Column(db.String(500))  # JSON格式存储团队成员
    is_featured = db.Column(db.Boolean, default=False)
    
    # 关联关系
    tasks = db.relationship('Task', backref='project', lazy=True, cascade='all, delete-orphan')

class Task(db.Model):
    """任务看板模型"""
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    status = db.Column(db.String(20), default='todo')  # todo, doing, done
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    assignee = db.Column(db.String(50))

class SecurityTip(db.Model):
    """安全知识小贴士模型"""
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    category = db.Column(db.String(50))  # 分类：web安全、系统安全、密码学等
    difficulty = db.Column(db.String(20), default='beginner')  # beginner, intermediate, advanced
    likes = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class UserFavorite(db.Model):
    """用户收藏模型"""
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.String(100), nullable=False)  # 简化处理，用session标识
    tip_id = db.Column(db.Integer, db.ForeignKey('security_tip.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 安全知识小贴士数据
SECURITY_TIPS = [
    {
        "title": "SQL注入攻击原理",
        "content": "SQL注入是通过将恶意SQL代码插入到查询语句中，从而操控数据库的攻击方式。预防方法：使用参数化查询、输入验证、最小权限原则。",
        "category": "Web安全",
        "difficulty": "beginner"
    },
    {
        "title": "XSS跨站脚本攻击",
        "content": "XSS攻击允许攻击者在用户浏览器中执行恶意脚本。分为存储型、反射型和DOM型。防御措施：输入过滤、输出编码、CSP策略。",
        "category": "Web安全",
        "difficulty": "beginner"
    },
    {
        "title": "密码哈希存储",
        "content": "永远不要明文存储密码！应使用bcrypt、scrypt或Argon2等慢哈希算法，并添加随机盐值。推荐成本因子：bcrypt至少12。",
        "category": "密码学",
        "difficulty": "intermediate"
    },
    {
        "title": "HTTPS的重要性",
        "content": "HTTPS通过TLS/SSL加密保护数据传输，防止中间人攻击。现代浏览器对HTTP网站显示'不安全'警告，HTTPS已成为标准。",
        "category": "网络安全",
        "difficulty": "beginner"
    },
    {
        "title": "防火墙基础概念",
        "content": "防火墙是网络安全的第一道防线，通过规则控制网络流量。了解iptables、ufw等工具，掌握端口管理和访问控制列表(ACL)。",
        "category": "系统安全",
        "difficulty": "intermediate"
    },
    {
        "title": "社会工程学防范",
        "content": "人是安全链中最薄弱的一环。学会识别钓鱼邮件、虚假电话等社会工程攻击。记住：技术可以很强，但人的因素需要持续教育。",
        "category": "安全意识",
        "difficulty": "beginner"
    },
    {
        "title": "零信任安全模型",
        "content": "零信任原则：永不信任，始终验证。无论请求来自内部还是外部，都需要进行身份验证和授权。这是现代网络安全的重要理念。",
        "category": "网络安全",
        "difficulty": "advanced"
    },
    {
        "title": "日志分析与监控",
        "content": "安全日志是发现攻击的关键。学会使用ELK、Splunk等工具分析日志。关注异常登录、权限变更、系统调用等关键事件。",
        "category": "安全运维",
        "difficulty": "intermediate"
    }
]

# 路由定义
@app.route('/')
def index():
    """首页 - 展示优秀项目和每日安全贴士"""
    featured_projects = Project.query.filter_by(is_featured=True).order_by(Project.created_at.desc()).limit(3).all()
    
    # 获取今日安全贴士
    today = date.today()
    tip_index = (today.toordinal() - 1) % len(SECURITY_TIPS)
    today_tip_data = SECURITY_TIPS[tip_index]
    
    # 检查是否已存在今日贴士
    today_tip = SecurityTip.query.filter_by(
        title=today_tip_data['title'],
        created_at=datetime.combine(today, datetime.min.time())
    ).first()
    
    if not today_tip:
        today_tip = SecurityTip(
            title=today_tip_data['title'],
            content=today_tip_data['content'],
            category=today_tip_data['category'],
            difficulty=today_tip_data['difficulty']
        )
        db.session.add(today_tip)
        db.session.commit()
    
    return render_template('index.html', 
                         featured_projects=featured_projects,
                         today_tip=today_tip)

@app.route('/projects')
def projects():
    """项目列表页"""
    all_projects = Project.query.order_by(Project.created_at.desc()).all()
    return render_template('projects.html', projects=all_projects)

@app.route('/project/<int:project_id>')
def project_detail(project_id):
    """项目详情页"""
    project = Project.query.get_or_404(project_id)
    tasks = Task.query.filter_by(project_id=project_id).all()
    return render_template('project_detail.html', project=project, tasks=tasks)

@app.route('/create_project', methods=['GET', 'POST'])
def create_project():
    """创建新项目"""
    if request.method == 'POST':
        data = request.get_json()
        
        project = Project(
            name=data['name'],
            description=data['description'],
            github_url=data.get('github_url', ''),
            team_members=json.dumps(data.get('team_members', []))
        )
        
        db.session.add(project)
        db.session.commit()
        
        return jsonify({'success': True, 'project_id': project.id})
    
    return render_template('create_project.html')

@app.route('/api/projects/<int:project_id>/tasks', methods=['GET', 'POST'])
def project_tasks(project_id):
    """项目任务管理"""
    if request.method == 'POST':
        data = request.get_json()
        
        task = Task(
            title=data['title'],
            description=data.get('description', ''),
            status=data.get('status', 'todo'),
            project_id=project_id,
            assignee=data.get('assignee', '')
        )
        
        db.session.add(task)
        db.session.commit()
        
        return jsonify({'success': True, 'task_id': task.id})
    
    tasks = Task.query.filter_by(project_id=project_id).all()
    return jsonify([{
        'id': task.id,
        'title': task.title,
        'description': task.description,
        'status': task.status,
        'assignee': task.assignee,
        'created_at': task.created_at.isoformat()
    } for task in tasks])

@app.route('/api/tasks/<int:task_id>', methods=['PUT', 'DELETE'])
def update_task(task_id):
    """更新或删除任务"""
    task = Task.query.get_or_404(task_id)
    
    if request.method == 'PUT':
        data = request.get_json()
        task.status = data.get('status', task.status)
        task.assignee = data.get('assignee', task.assignee)
        db.session.commit()
        return jsonify({'success': True})
    
    elif request.method == 'DELETE':
        db.session.delete(task)
        db.session.commit()
        return jsonify({'success': True})

@app.route('/security_tips')
def security_tips():
    """安全知识小贴士页面"""
    tips = SecurityTip.query.order_by(SecurityTip.created_at.desc()).all()
    return render_template('security_tips.html', tips=tips)

@app.route('/api/tips/<int:tip_id>/like', methods=['POST'])
def like_tip(tip_id):
    """点赞安全贴士"""
    tip = SecurityTip.query.get_or_404(tip_id)
    tip.likes += 1
    db.session.commit()
    return jsonify({'likes': tip.likes})

@app.route('/roadshow/<int:project_id>')
def roadshow(project_id):
    """路演工具页面"""
    project = Project.query.get_or_404(project_id)
    return render_template('roadshow.html', project=project)

@app.route('/api/generate_poster/<int:project_id>')
def generate_poster(project_id):
    """生成项目海报"""
    project = Project.query.get_or_404(project_id)
    
    # 生成二维码
    qr = qrcode.QRCode(version=1, box_size=10, border=5)
    qr.add_data(project.github_url or f'http://localhost:5000/project/{project_id}')
    qr.make(fit=True)
    
    # 创建海报HTML
    poster_html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>{project.name} - 项目海报</title>
        <style>
            body {{ font-family: Arial, sans-serif; margin: 40px; }}
            .poster {{ max-width: 800px; margin: 0 auto; border: 2px solid #333; padding: 40px; }}
            .header {{ text-align: center; margin-bottom: 30px; }}
            .title {{ font-size: 2.5em; color: #2c3e50; margin-bottom: 10px; }}
            .subtitle {{ font-size: 1.2em; color: #7f8c8d; }}
            .content {{ margin: 30px 0; }}
            .description {{ font-size: 1.1em; line-height: 1.6; margin-bottom: 20px; }}
            .team {{ background: #f8f9fa; padding: 20px; border-radius: 8px; }}
            .qr-code {{ text-align: center; margin-top: 30px; }}
            .footer {{ text-align: center; margin-top: 40px; color: #95a5a6; }}
        </style>
    </head>
    <body>
        <div class="poster">
            <div class="header">
                <h1 class="title">{project.name}</h1>
                <p class="subtitle">开源安全创意工坊项目</p>
            </div>
            
            <div class="content">
                <div class="description">
                    <h3>项目简介</h3>
                    <p>{project.description}</p>
                </div>
                
                <div class="team">
                    <h3>团队成员</h3>
                    <p>{json.loads(project.team_members) if project.team_members else '暂无成员信息'}</p>
                </div>
                
                <div class="qr-code">
                    <h4>扫码查看项目详情</h4>
                    <img src="data:image/png;base64,{generate_qr_code_base64(project.github_url or f'http://localhost:5000/project/{project_id}')}" alt="QR Code">
                </div>
            </div>
            
            <div class="footer">
                <p>生成时间：{datetime.now().strftime('%Y年%m月%d日')}</p>
                <p>开源安全创意工坊 - 培养下一代网络安全创新者</p>
            </div>
        </div>
    </body>
    </html>
    """
    
    # 生成PDF
    font_config = FontConfiguration()
    pdf_bytes = HTML(string=poster_html).write_pdf(font_config=font_config)
    
    return send_file(
        BytesIO(pdf_bytes),
        mimetype='application/pdf',
        as_attachment=True,
        download_name=f'{project.name}_poster.pdf'
    )

def generate_qr_code_base64(url):
    """生成二维码的base64编码"""
    qr = qrcode.QRCode(version=1, box_size=10, border=5)
    qr.add_data(url)
    qr.make(fit=True)
    
    from PIL import Image
    import base64
    
    img = qr.make_image(fill_color="black", back_color="white")
    buffered = BytesIO()
    img.save(buffered, format="PNG")
    img_str = base64.b64encode(buffered.getvalue()).decode()
    return img_str

@app.route('/api/export_projects')
def export_projects():
    """导出所有项目信息（教师功能）"""
    projects = Project.query.all()
    project_data = []
    
    for project in projects:
        project_data.append({
            'id': project.id,
            'name': project.name,
            'description': project.description,
            'github_url': project.github_url,
            'created_at': project.created_at.isoformat(),
            'team_members': json.loads(project.team_members) if project.team_members else [],
            'task_count': len(project.tasks)
        })
    
    return jsonify(project_data)

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500

# 初始化数据库
def init_db():
    """初始化数据库和示例数据"""
    with app.app_context():
        db.create_all()
        
        # 添加一些示例项目
        if Project.query.count() == 0:
            sample_projects = [
                {
                    'name': '智能防火墙系统',
                    'description': '基于机器学习的智能防火墙，能够自动识别和阻止恶意流量',
                    'github_url': 'https://github.com/example/smart-firewall',
                    'team_members': json.dumps(['张三', '李四', '王五']),
                    'is_featured': True
                },
                {
                    'name': '密码强度检测器',
                    'description': '一个开源的密码强度检测工具，帮助用户创建更安全的密码',
                    'github_url': 'https://github.com/example/password-strength',
                    'team_members': json.dumps(['赵六', '钱七']),
                    'is_featured': True
                }
            ]
            
            for project_data in sample_projects:
                project = Project(**project_data)
                db.session.add(project)
            
            db.session.commit()

if __name__ == '__main__':
    init_db()
    app.run(debug=True, host='0.0.0.0', port=5000)
